from research.calcor import calcor_base
class dd_trend_bybar(calcor_base):
    def __init__(self,factor=0.005):
        super().__init__(datatype="bar")
        self.factor=factor#默认千1
        self.fx=0
    def calc(self):
        b=self.hisdata[-1]
        preb=self.hisdata[0]
        if self.fx > 0:  # 上涨中找顶
            if b["low"]<preb["low"]*(1-self.factor):
                p=max(preb["open"],preb["close"])
                if b["close"]<=p*(1-self.factor):
                    self.fx=-2
            if self.fx==2:
                self.fx=1
        elif self.fx < 0:  # 下跌中找堤
            if b["high"]>preb["high"]*(1+self.factor):
                p=min(preb["open"],preb["close"])
                if b["close"]>=p*(1+self.factor):
                    self.fx=2
            if self.fx==-2:
                self.fx=-1
        else:
            if b["high"] > preb["high"] * (1 + self.factor):
                self.fx=1
            elif b["low"]<preb["low"]*(1-self.factor):
                self.fx=-1
        rst=self.fx
        return rst
class dd_trend_bars_bybar(calcor_base):
    def __init__(self,bars=2,isclose=True):
        super().__init__(timeperiod=bars+1,datatype="bar")
        self.fx=0
        if isclose:
            self.calc=self.calc_True
        else:
            self.calc = self.calc_False
    def calc_False(self):
        b=self.hisdata[-1]
        prebs=self.hisdata[:-1]
        if self.fx > 0:
            r = True
            for preb in prebs:
                r = r and b["close"] < preb["close"] and b["low"] < preb["low"]
                if not r:
                    break
            if self.fx == 2:
                self.fx = 1
            if r:
                self.fx = -2
        elif self.fx < 0:
            r = True
            for preb in prebs:
                r = r and b["close"] > preb["close"] and b["high"] > preb["high"]
                if not r:
                    break
            if self.fx == -2:
                self.fx = -1
            if r:
                self.fx = 2
        else:
            if b["close"] > prebs[-1]["close"]:
                self.fx = 1
            elif b["close"] < prebs[-1]["close"]:
                self.fx = -1
        rst = self.fx
        return rst
    def calc_True(self):
        b = self.hisdata[-1]
        prebs = self.hisdata[:-1]
        if self.fx>0:
            r=True
            for preb in prebs:
                r=r and b["close"]<preb["low"]
                if not r:
                    break
            if self.fx==2:
                self.fx=1
            if r:
                self.fx=-2
        elif self.fx<0:
            r = True
            for preb in prebs:
                r = r and b["close"] > preb["high"]
                if not r:
                    break
            if self.fx == -2:
                self.fx = -1
            if r:
                self.fx = 2
        else:
            if b["close"]>prebs[-1]["close"]:
                self.fx=1
            elif b["close"]<prebs[-1]["close"]:
                self.fx=-1
        rst=self.fx
        return rst

class dd_bars_n_bybar(calcor_base):
    def __init__(self,isclose=True,timeperiod=10,isbreak=True):
        super().__init__(timeperiod=timeperiod+1,datatype="bar")
        self.isbreak=isbreak
        if isclose:
            self.calc=self.calc_True
        else:
            self.calc = self.calc_False
    def calc_False(self):
        up = 0
        down = 0
        r_up = True
        r_down=True
        isbreak_up=False
        isbreak_down=False
        b=self.hisdata[-1]
        prebs=self.hisdata[:-1]
        for i in reversed(prebs):
            if self.isbreak:
                r_up = r_up and b["close"] > i["close"] and b["high"] < i["high"]
                r_down = r_down and b["close"] < i["close"] and b["low"] < i["low"]
                if not r_up:
                    isbreak_up=True
                if not r_down:
                    isbreak_down=True
                if not isbreak_up:
                    up=up+1
                if not isbreak_down:
                    down=down+1
                if isbreak_up and isbreak_up:
                    break
            else:
                r_up = b["close"] > i["close"] and b["high"] < i["high"]
                r_down = b["close"] < i["close"] and b["low"] < i["low"]
                if r_up:
                    up = up + 1
                if r_down:
                    down=down+1
        return up,-down
    def calc_True(self):
        up = 0
        down = 0
        r_up = True
        r_down = True
        isbreak_up = False
        isbreak_down = False
        b=self.hisdata[-1]
        prebs=self.hisdata[:-1]
        for i in reversed(prebs):
            if self.isbreak:
                r_up = r_up and b["close"] > i["high"]
                r_down = r_down and b["close"] < i["low"]
                if not r_up:
                    isbreak_up = True
                if not r_down:
                    isbreak_down = True
                if not isbreak_up:
                    up = up + 1
                if not isbreak_down:
                    down = down + 1
                if isbreak_up and isbreak_up:
                    break
            else:
                r_up = b["close"] > i["high"]
                r_down = b["close"] < i["low"]
                if r_up:
                    up = up + 1
                if r_down:
                    down = down + 1
        return up, -down
if __name__=="__main__":
    cc=[
        {'calc_cmd': 'class', "class": "dd_trend", "out": ["dd_trend0"],
         "init_args": {"factor": 0}},
        {'calc_cmd': 'class', "class": "dd_trend", "out": ["dd_trend1"],
         "init_args": {"factor": 0.005}},
        {'calc_cmd': 'class', "class": "dd_trend", "out": ["dd_trend2"],
         "init_args": {"factor": 0.01}},
        {'calc_cmd': 'class', "class": "dd_trend_bars", "out": ["dd_trends1True"],
         "init_args": {"bars":1,"isclose":True}},
        {'calc_cmd': 'class', "class": "dd_trend_bars", "out": ["dd_trends2True"],
         "init_args": {"bars": 2, "isclose": True}},
        {'calc_cmd': 'class', "class": "dd_trend_bars", "out": ["dd_trends3True"],
         "init_args": {"bars": 3, "isclose": True}},
        {'calc_cmd': 'class', "class": "dd_trend_bars", "out": ["dd_trends1False"],
         "init_args": {"bars": 1, "isclose": False}},
        {'calc_cmd': 'class', "class": "dd_trend_bars", "out": ["dd_trends2False"],
         "init_args": {"bars": 2, "isclose": False}},
        {'calc_cmd': 'class', "class": "dd_trend_bars", "out": ["dd_trends3False"],
         "init_args": {"bars": 3, "isclose": False}},
        {'calc_cmd': 'class', "class": "dd_bars_n", "out": ["dd_bars_n3True_up","dd_bars_n3True_down"],
         "init_args": {"maxn": 3, "isclose": True}},
        {'calc_cmd': 'class', "class": "dd_bars_n", "out": ["dd_bars_n5True_up","dd_bars_n5True_down"],
         "init_args": {"maxn": 5, "isclose": True}},
        {'calc_cmd': 'class', "class": "dd_bars_n", "out": ["dd_bars_n10True_up","dd_bars_n10True_down"],
         "init_args": {"maxn": 10, "isclose": True}},
        {'calc_cmd': 'class', "class": "dd_bars_n", "out": ["dd_bars_n3False_up","dd_bars_n3False_down"],
         "init_args": {"maxn": 3, "isclose": False}},
        {'calc_cmd': 'class', "class": "dd_bars_n", "out": ["dd_bars_n5False_up","dd_bars_n5False_down"],
         "init_args": {"maxn": 5, "isclose": False}},
        {'calc_cmd': 'class', "class": "dd_bars_n", "out": ["dd_bars_n10False_up","dd_bars_n10False_down"],
         "init_args": {"maxn": 10, "isclose": False}},
        {'calc_cmd': 'class', "class": "dd_bars_n", "out": ["dd0_bars_n3True_up", "dd0_bars_n3True_down"],
         "init_args": {"maxn": 3, "isclose": True,"isbreak":False}},
        {'calc_cmd': 'class', "class": "dd_bars_n", "out": ["dd0_bars_n5True_up", "dd0_bars_n5True_down"],
         "init_args": {"maxn": 5, "isclose": True,"isbreak":False}},
        {'calc_cmd': 'class', "class": "dd_bars_n", "out": ["dd0_bars_n10True_up", "dd0_bars_n10True_down"],
         "init_args": {"maxn": 10, "isclose": True,"isbreak":False}},
        {'calc_cmd': 'class', "class": "dd_bars_n", "out": ["dd0_bars_n3False_up", "dd0_bars_n3False_down"],
         "init_args": {"maxn": 3, "isclose": False,"isbreak":False}},
        {'calc_cmd': 'class', "class": "dd_bars_n", "out": ["dd0_bars_n5False_up", "dd0_bars_n5False_down"],
         "init_args": {"maxn": 5, "isclose": False,"isbreak":False}},
        {'calc_cmd': 'class', "class": "dd_bars_n", "out": ["dd0_bars_n10False_up", "dd0_bars_n10False_down"],
         "init_args": {"maxn": 10, "isclose": False,"isbreak":False}}
    ]
    from research.calcor.calcor_show import calcor_show

    calcor_show(obj="ec888",start="20240103",end="20240731",cc=cc,factors=[],prebatch=10,main_names=[],
                sub_names=[
                    ("line", ["dd0_bars_n3True_up", "dd0_bars_n5True_up", "dd0_bars_n10True_up",
                              "dd0_bars_n3False_up", "dd0_bars_n5False_up", "dd0_bars_n10False_up"]),
                    ("line", ["dd0_bars_n3True_down", "dd0_bars_n5True_down", "dd0_bars_n10True_down",
                              "dd0_bars_n3False_down", "dd0_bars_n5False_down", "dd0_bars_n10False_down"]),
                    ("line", ["dd_bars_n3True_up", "dd_bars_n5True_up", "dd_bars_n10True_up",
                              "dd_bars_n3False_up", "dd_bars_n5False_up", "dd_bars_n10False_up"]),
                    ("line", ["dd_bars_n3True_down", "dd_bars_n5True_down", "dd_bars_n10True_down",
                              "dd_bars_n3False_down", "dd_bars_n5False_down", "dd_bars_n10False_down"]),
                    ("line", ["dd_trends1True", "dd_trends2True", "dd_trends3True",
                              "dd_trends1False", "dd_trends2False", "dd_trends3False"]),
                    ("line",["dd_trend0","dd_trend1","dd_trend2"])])